/*
 * Copyright (c) United Binary LLC.  All rights reserved.
 * 
 * This code is licensed under the MIT License
 * 
 * SEE: http://harnessit.codeplex.com/license
 * 
 */
using System;
using System.Diagnostics;
using System.Collections;
using System.ComponentModel;
using System.Drawing;
using System.Windows.Forms;

using UnitedBinary.UnitTests.Framework.TestItems;
using UnitedBinary.Core.Diagnostics;

namespace UnitedBinary.HarnessIt.Controls
{
	/// <summary>
	/// Summary description for ExceptionExplorerControl.
	/// </summary>
	public class ExceptionExplorerControl : System.Windows.Forms.UserControl
	{
		private Crownwood.Magic.Controls.TabControl tabControlExceptionExplorerPages;
		private Crownwood.Magic.Controls.TabPage tabPageStandardInfo;
		private Crownwood.Magic.Controls.TabPage tabPageToString;
		private System.Windows.Forms.TextBox textBoxMessage;
		private System.Windows.Forms.TextBox textBoxSource;
		private System.Windows.Forms.ColumnHeader columnHeaderLine;
		private System.Windows.Forms.ColumnHeader columnHeaderNamespace;
		private System.Windows.Forms.ColumnHeader columnHeaderClass;
		private System.Windows.Forms.ColumnHeader columnHeaderMethod;
		private System.Windows.Forms.ColumnHeader columnHeaderFile;
		private System.Windows.Forms.Label label5;
		private System.Windows.Forms.Label label4;
		private System.Windows.Forms.Label label2;
		private System.Windows.Forms.TextBox textBoxType;
		private System.Windows.Forms.Label label3;
		private System.Windows.Forms.Label label7;
		private System.Windows.Forms.TextBox textBoxToString;
		private System.ComponentModel.IContainer components;
		private System.Windows.Forms.ListView listViewStackTrace;
		private string associatedTestPath = "";
		private System.Windows.Forms.Label label8;
		private System.Windows.Forms.TextBox textBoxTestMethod;
		private ExceptionExplorerStackTracePersistence stPersist;

		private ArrayList exceptionHierarchy = new ArrayList();
		private int currentExceptionIndex = 0;
		private System.Windows.Forms.Timer timerUpdatePersistence;
		private System.Windows.Forms.Label labelParentException;
		private System.Windows.Forms.Label labelParentExceptionTitle;
		private System.Windows.Forms.Label labelInnerException;
		private System.Windows.Forms.Label labelInnerExceptionTitle;
		private System.Windows.Forms.TextBox textBoxThreadID;
		private System.Windows.Forms.Label label1;
		private System.Windows.Forms.Label label6;
		private System.Windows.Forms.TextBox textBoxThreadName;

		public delegate void CurrentExceptionChanged(TestException te, string AssociatedTestPath);
		public event CurrentExceptionChanged CurrentExceptionChangedHandler;

		private string initialNoExceptionMessage = "";

		public ExceptionExplorerControl()
		{
			//
			// This call is required by the Windows.Forms Form Designer.
			//
			InitializeComponent();

			//
			// Add any initialization after the InitForm call
			//
			SelectEveryTabPage();
			initialNoExceptionMessage = textBoxMessage.Text;

			stPersist = new ExceptionExplorerStackTracePersistence(listViewStackTrace);
			stPersist.Initialize();
			timerUpdatePersistence.Start();
		}

		/// <summary> 
		/// Clean up any resources being used.
		/// </summary>
		protected override void Dispose( bool disposing )
		{
			if( disposing )
			{
				if(components != null)
				{
					components.Dispose();
				}
			}
			base.Dispose( disposing );
		}

		#region Component Designer generated code
		/// <summary> 
		/// Required method for Designer support - do not modify 
		/// the contents of this method with the code editor.
		/// </summary>
		private void InitializeComponent()
		{
			this.components = new System.ComponentModel.Container();
			this.tabControlExceptionExplorerPages = new Crownwood.Magic.Controls.TabControl();
			this.tabPageStandardInfo = new Crownwood.Magic.Controls.TabPage();
			this.textBoxThreadName = new System.Windows.Forms.TextBox();
			this.label6 = new System.Windows.Forms.Label();
			this.textBoxThreadID = new System.Windows.Forms.TextBox();
			this.label1 = new System.Windows.Forms.Label();
			this.textBoxTestMethod = new System.Windows.Forms.TextBox();
			this.label8 = new System.Windows.Forms.Label();
			this.textBoxType = new System.Windows.Forms.TextBox();
			this.label3 = new System.Windows.Forms.Label();
			this.textBoxMessage = new System.Windows.Forms.TextBox();
			this.textBoxSource = new System.Windows.Forms.TextBox();
			this.listViewStackTrace = new System.Windows.Forms.ListView();
			this.columnHeaderMethod = new System.Windows.Forms.ColumnHeader();
			this.columnHeaderClass = new System.Windows.Forms.ColumnHeader();
			this.columnHeaderLine = new System.Windows.Forms.ColumnHeader();
			this.columnHeaderFile = new System.Windows.Forms.ColumnHeader();
			this.columnHeaderNamespace = new System.Windows.Forms.ColumnHeader();
			this.label5 = new System.Windows.Forms.Label();
			this.label4 = new System.Windows.Forms.Label();
			this.label2 = new System.Windows.Forms.Label();
			this.tabPageToString = new Crownwood.Magic.Controls.TabPage();
			this.label7 = new System.Windows.Forms.Label();
			this.textBoxToString = new System.Windows.Forms.TextBox();
			this.timerUpdatePersistence = new System.Windows.Forms.Timer(this.components);
			this.labelParentException = new System.Windows.Forms.Label();
			this.labelParentExceptionTitle = new System.Windows.Forms.Label();
			this.labelInnerException = new System.Windows.Forms.Label();
			this.labelInnerExceptionTitle = new System.Windows.Forms.Label();
			this.tabControlExceptionExplorerPages.SuspendLayout();
			this.tabPageStandardInfo.SuspendLayout();
			this.tabPageToString.SuspendLayout();
			this.SuspendLayout();
			// 
			// tabControlExceptionExplorerPages
			// 
			this.tabControlExceptionExplorerPages.Anchor = (((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) 
				| System.Windows.Forms.AnchorStyles.Left) 
				| System.Windows.Forms.AnchorStyles.Right);
			this.tabControlExceptionExplorerPages.HotTrack = true;
			this.tabControlExceptionExplorerPages.IDEPixelArea = true;
			this.tabControlExceptionExplorerPages.Name = "tabControlExceptionExplorerPages";
			this.tabControlExceptionExplorerPages.PositionTop = true;
			this.tabControlExceptionExplorerPages.SelectedIndex = 0;
			this.tabControlExceptionExplorerPages.SelectedTab = this.tabPageStandardInfo;
			this.tabControlExceptionExplorerPages.Size = new System.Drawing.Size(404, 334);
			this.tabControlExceptionExplorerPages.TabIndex = 0;
			this.tabControlExceptionExplorerPages.TabPages.AddRange(new Crownwood.Magic.Controls.TabPage[] {
																											   this.tabPageStandardInfo,
																											   this.tabPageToString});
			// 
			// tabPageStandardInfo
			// 
			this.tabPageStandardInfo.BackColor = System.Drawing.SystemColors.Window;
			this.tabPageStandardInfo.Controls.AddRange(new System.Windows.Forms.Control[] {
																							  this.textBoxThreadName,
																							  this.label6,
																							  this.textBoxThreadID,
																							  this.label1,
																							  this.textBoxTestMethod,
																							  this.label8,
																							  this.textBoxType,
																							  this.label3,
																							  this.textBoxMessage,
																							  this.textBoxSource,
																							  this.listViewStackTrace,
																							  this.label5,
																							  this.label4,
																							  this.label2});
			this.tabPageStandardInfo.Font = new System.Drawing.Font("Tahoma", 8.5F);
			this.tabPageStandardInfo.Location = new System.Drawing.Point(0, 25);
			this.tabPageStandardInfo.Name = "tabPageStandardInfo";
			this.tabPageStandardInfo.Size = new System.Drawing.Size(404, 309);
			this.tabPageStandardInfo.TabIndex = 0;
			this.tabPageStandardInfo.Title = "Standard Information";
			// 
			// textBoxThreadName
			// 
			this.textBoxThreadName.Anchor = ((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) 
				| System.Windows.Forms.AnchorStyles.Right);
			this.textBoxThreadName.BackColor = System.Drawing.Color.White;
			this.textBoxThreadName.Font = new System.Drawing.Font("Tahoma", 8.5F);
			this.textBoxThreadName.Location = new System.Drawing.Point(124, 208);
			this.textBoxThreadName.Name = "textBoxThreadName";
			this.textBoxThreadName.ReadOnly = true;
			this.textBoxThreadName.Size = new System.Drawing.Size(264, 21);
			this.textBoxThreadName.TabIndex = 15;
			this.textBoxThreadName.Text = "";
			// 
			// label6
			// 
			this.label6.BackColor = System.Drawing.Color.White;
			this.label6.Font = new System.Drawing.Font("Tahoma", 8.5F);
			this.label6.Location = new System.Drawing.Point(104, 192);
			this.label6.Name = "label6";
			this.label6.Size = new System.Drawing.Size(228, 16);
			this.label6.TabIndex = 16;
			this.label6.Text = "Thread Name";
			// 
			// textBoxThreadID
			// 
			this.textBoxThreadID.BackColor = System.Drawing.Color.White;
			this.textBoxThreadID.Font = new System.Drawing.Font("Tahoma", 8.5F);
			this.textBoxThreadID.Location = new System.Drawing.Point(24, 208);
			this.textBoxThreadID.Name = "textBoxThreadID";
			this.textBoxThreadID.ReadOnly = true;
			this.textBoxThreadID.Size = new System.Drawing.Size(88, 21);
			this.textBoxThreadID.TabIndex = 13;
			this.textBoxThreadID.Text = "";
			// 
			// label1
			// 
			this.label1.BackColor = System.Drawing.Color.White;
			this.label1.Font = new System.Drawing.Font("Tahoma", 8.5F);
			this.label1.Location = new System.Drawing.Point(8, 192);
			this.label1.Name = "label1";
			this.label1.Size = new System.Drawing.Size(56, 16);
			this.label1.TabIndex = 14;
			this.label1.Text = "Thread ID";
			// 
			// textBoxTestMethod
			// 
			this.textBoxTestMethod.Anchor = ((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) 
				| System.Windows.Forms.AnchorStyles.Right);
			this.textBoxTestMethod.BackColor = System.Drawing.Color.White;
			this.textBoxTestMethod.Font = new System.Drawing.Font("Tahoma", 8.5F);
			this.textBoxTestMethod.Location = new System.Drawing.Point(24, 24);
			this.textBoxTestMethod.Name = "textBoxTestMethod";
			this.textBoxTestMethod.ReadOnly = true;
			this.textBoxTestMethod.Size = new System.Drawing.Size(364, 21);
			this.textBoxTestMethod.TabIndex = 12;
			this.textBoxTestMethod.Text = "";
			// 
			// label8
			// 
			this.label8.Anchor = ((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) 
				| System.Windows.Forms.AnchorStyles.Right);
			this.label8.BackColor = System.Drawing.Color.White;
			this.label8.Font = new System.Drawing.Font("Tahoma", 8.5F);
			this.label8.Location = new System.Drawing.Point(8, 8);
			this.label8.Name = "label8";
			this.label8.Size = new System.Drawing.Size(380, 16);
			this.label8.TabIndex = 11;
			this.label8.Text = "Test Method   (Assembly.Class.Method)";
			// 
			// textBoxType
			// 
			this.textBoxType.Anchor = ((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) 
				| System.Windows.Forms.AnchorStyles.Right);
			this.textBoxType.BackColor = System.Drawing.Color.White;
			this.textBoxType.Font = new System.Drawing.Font("Tahoma", 8.5F);
			this.textBoxType.Location = new System.Drawing.Point(24, 64);
			this.textBoxType.Name = "textBoxType";
			this.textBoxType.ReadOnly = true;
			this.textBoxType.Size = new System.Drawing.Size(364, 21);
			this.textBoxType.TabIndex = 1;
			this.textBoxType.Text = "";
			// 
			// label3
			// 
			this.label3.BackColor = System.Drawing.Color.White;
			this.label3.Font = new System.Drawing.Font("Tahoma", 8.5F);
			this.label3.Location = new System.Drawing.Point(8, 48);
			this.label3.Name = "label3";
			this.label3.Size = new System.Drawing.Size(56, 16);
			this.label3.TabIndex = 9;
			this.label3.Text = "Type";
			// 
			// textBoxMessage
			// 
			this.textBoxMessage.Anchor = ((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) 
				| System.Windows.Forms.AnchorStyles.Right);
			this.textBoxMessage.BackColor = System.Drawing.Color.White;
			this.textBoxMessage.Font = new System.Drawing.Font("Tahoma", 8.5F);
			this.textBoxMessage.Location = new System.Drawing.Point(24, 104);
			this.textBoxMessage.Multiline = true;
			this.textBoxMessage.Name = "textBoxMessage";
			this.textBoxMessage.ReadOnly = true;
			this.textBoxMessage.ScrollBars = System.Windows.Forms.ScrollBars.Vertical;
			this.textBoxMessage.Size = new System.Drawing.Size(364, 48);
			this.textBoxMessage.TabIndex = 2;
			this.textBoxMessage.Text = "No exception loaded. Choose an exception to view in the Report Explorer, Output, or Failures windows.";
			// 
			// textBoxSource
			// 
			this.textBoxSource.Anchor = ((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) 
				| System.Windows.Forms.AnchorStyles.Right);
			this.textBoxSource.BackColor = System.Drawing.Color.White;
			this.textBoxSource.Font = new System.Drawing.Font("Tahoma", 8.5F);
			this.textBoxSource.Location = new System.Drawing.Point(24, 168);
			this.textBoxSource.Name = "textBoxSource";
			this.textBoxSource.ReadOnly = true;
			this.textBoxSource.Size = new System.Drawing.Size(364, 21);
			this.textBoxSource.TabIndex = 3;
			this.textBoxSource.Text = "";
			// 
			// listViewStackTrace
			// 
			this.listViewStackTrace.Anchor = (((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) 
				| System.Windows.Forms.AnchorStyles.Left) 
				| System.Windows.Forms.AnchorStyles.Right);
			this.listViewStackTrace.BackColor = System.Drawing.Color.White;
			this.listViewStackTrace.Columns.AddRange(new System.Windows.Forms.ColumnHeader[] {
																								 this.columnHeaderMethod,
																								 this.columnHeaderClass,
																								 this.columnHeaderLine,
																								 this.columnHeaderFile,
																								 this.columnHeaderNamespace});
			this.listViewStackTrace.Font = new System.Drawing.Font("Tahoma", 8.5F);
			this.listViewStackTrace.FullRowSelect = true;
			this.listViewStackTrace.GridLines = true;
			this.listViewStackTrace.HeaderStyle = System.Windows.Forms.ColumnHeaderStyle.Nonclickable;
			this.listViewStackTrace.Location = new System.Drawing.Point(24, 248);
			this.listViewStackTrace.MultiSelect = false;
			this.listViewStackTrace.Name = "listViewStackTrace";
			this.listViewStackTrace.Size = new System.Drawing.Size(364, 52);
			this.listViewStackTrace.TabIndex = 0;
			this.listViewStackTrace.View = System.Windows.Forms.View.Details;
			// 
			// columnHeaderMethod
			// 
			this.columnHeaderMethod.Text = "Method";
			this.columnHeaderMethod.Width = 100;
			// 
			// columnHeaderClass
			// 
			this.columnHeaderClass.Text = "Class";
			this.columnHeaderClass.Width = 120;
			// 
			// columnHeaderLine
			// 
			this.columnHeaderLine.Text = "Line";
			this.columnHeaderLine.TextAlign = System.Windows.Forms.HorizontalAlignment.Right;
			this.columnHeaderLine.Width = 40;
			// 
			// columnHeaderFile
			// 
			this.columnHeaderFile.Text = "File";
			this.columnHeaderFile.Width = 100;
			// 
			// columnHeaderNamespace
			// 
			this.columnHeaderNamespace.Text = "Namespace";
			this.columnHeaderNamespace.Width = 200;
			// 
			// label5
			// 
			this.label5.BackColor = System.Drawing.Color.White;
			this.label5.Font = new System.Drawing.Font("Tahoma", 8.5F);
			this.label5.Location = new System.Drawing.Point(8, 232);
			this.label5.Name = "label5";
			this.label5.Size = new System.Drawing.Size(72, 16);
			this.label5.TabIndex = 6;
			this.label5.Text = "Stack Trace";
			// 
			// label4
			// 
			this.label4.BackColor = System.Drawing.Color.White;
			this.label4.Font = new System.Drawing.Font("Tahoma", 8.5F);
			this.label4.Location = new System.Drawing.Point(8, 152);
			this.label4.Name = "label4";
			this.label4.Size = new System.Drawing.Size(56, 16);
			this.label4.TabIndex = 7;
			this.label4.Text = "Source";
			// 
			// label2
			// 
			this.label2.BackColor = System.Drawing.Color.White;
			this.label2.Font = new System.Drawing.Font("Tahoma", 8.5F);
			this.label2.Location = new System.Drawing.Point(8, 88);
			this.label2.Name = "label2";
			this.label2.Size = new System.Drawing.Size(56, 16);
			this.label2.TabIndex = 8;
			this.label2.Text = "Message";
			// 
			// tabPageToString
			// 
			this.tabPageToString.BackColor = System.Drawing.Color.White;
			this.tabPageToString.Controls.AddRange(new System.Windows.Forms.Control[] {
																						  this.label7,
																						  this.textBoxToString});
			this.tabPageToString.Font = new System.Drawing.Font("Tahoma", 8.5F);
			this.tabPageToString.Location = new System.Drawing.Point(0, 25);
			this.tabPageToString.Name = "tabPageToString";
			this.tabPageToString.Selected = false;
			this.tabPageToString.Size = new System.Drawing.Size(404, 309);
			this.tabPageToString.TabIndex = 0;
			this.tabPageToString.Title = "ToString()";
			// 
			// label7
			// 
			this.label7.BackColor = System.Drawing.Color.White;
			this.label7.Font = new System.Drawing.Font("Tahoma", 8.5F);
			this.label7.Location = new System.Drawing.Point(8, 8);
			this.label7.Name = "label7";
			this.label7.Size = new System.Drawing.Size(100, 16);
			this.label7.TabIndex = 1;
			this.label7.Text = "ToString Output";
			// 
			// textBoxToString
			// 
			this.textBoxToString.Anchor = (((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) 
				| System.Windows.Forms.AnchorStyles.Left) 
				| System.Windows.Forms.AnchorStyles.Right);
			this.textBoxToString.BackColor = System.Drawing.Color.White;
			this.textBoxToString.Font = new System.Drawing.Font("Tahoma", 8.5F);
			this.textBoxToString.Location = new System.Drawing.Point(24, 24);
			this.textBoxToString.Multiline = true;
			this.textBoxToString.Name = "textBoxToString";
			this.textBoxToString.ReadOnly = true;
			this.textBoxToString.ScrollBars = System.Windows.Forms.ScrollBars.Vertical;
			this.textBoxToString.Size = new System.Drawing.Size(372, 276);
			this.textBoxToString.TabIndex = 0;
			this.textBoxToString.Text = "No exception loaded, choose an exception to view in the Output or Failures window" +
				".";
			// 
			// timerUpdatePersistence
			// 
			this.timerUpdatePersistence.Interval = 5000;
			this.timerUpdatePersistence.Tick += new System.EventHandler(this.timerUpdatePersistence_Tick);
			// 
			// labelParentException
			// 
			this.labelParentException.Anchor = ((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left) 
				| System.Windows.Forms.AnchorStyles.Right);
			this.labelParentException.BackColor = System.Drawing.Color.White;
			this.labelParentException.Font = new System.Drawing.Font("Tahoma", 8.5F);
			this.labelParentException.Location = new System.Drawing.Point(24, 352);
			this.labelParentException.Name = "labelParentException";
			this.labelParentException.Size = new System.Drawing.Size(364, 16);
			this.labelParentException.TabIndex = 17;
			this.labelParentException.Text = "None";
			this.labelParentException.Click += new System.EventHandler(this.labelParentException_Click);
			// 
			// labelParentExceptionTitle
			// 
			this.labelParentExceptionTitle.Anchor = ((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left) 
				| System.Windows.Forms.AnchorStyles.Right);
			this.labelParentExceptionTitle.BackColor = System.Drawing.Color.White;
			this.labelParentExceptionTitle.Font = new System.Drawing.Font("Tahoma", 8.5F);
			this.labelParentExceptionTitle.Location = new System.Drawing.Point(8, 336);
			this.labelParentExceptionTitle.Name = "labelParentExceptionTitle";
			this.labelParentExceptionTitle.Size = new System.Drawing.Size(380, 16);
			this.labelParentExceptionTitle.TabIndex = 18;
			this.labelParentExceptionTitle.Text = "Parent Exception";
			// 
			// labelInnerException
			// 
			this.labelInnerException.Anchor = ((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left) 
				| System.Windows.Forms.AnchorStyles.Right);
			this.labelInnerException.BackColor = System.Drawing.Color.White;
			this.labelInnerException.Cursor = System.Windows.Forms.Cursors.Default;
			this.labelInnerException.Font = new System.Drawing.Font("Tahoma", 8.5F);
			this.labelInnerException.Location = new System.Drawing.Point(24, 384);
			this.labelInnerException.Name = "labelInnerException";
			this.labelInnerException.Size = new System.Drawing.Size(364, 16);
			this.labelInnerException.TabIndex = 15;
			this.labelInnerException.Text = "None";
			this.labelInnerException.Click += new System.EventHandler(this.labelInnerException_Click);
			// 
			// labelInnerExceptionTitle
			// 
			this.labelInnerExceptionTitle.Anchor = ((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left) 
				| System.Windows.Forms.AnchorStyles.Right);
			this.labelInnerExceptionTitle.BackColor = System.Drawing.Color.White;
			this.labelInnerExceptionTitle.Font = new System.Drawing.Font("Tahoma", 8.5F);
			this.labelInnerExceptionTitle.Location = new System.Drawing.Point(8, 368);
			this.labelInnerExceptionTitle.Name = "labelInnerExceptionTitle";
			this.labelInnerExceptionTitle.Size = new System.Drawing.Size(380, 16);
			this.labelInnerExceptionTitle.TabIndex = 16;
			this.labelInnerExceptionTitle.Text = "Inner Exception";
			// 
			// ExceptionExplorerControl
			// 
			this.AutoScroll = true;
			this.AutoScrollMinSize = new System.Drawing.Size(368, 404);
			this.BackColor = System.Drawing.SystemColors.Window;
			this.Controls.AddRange(new System.Windows.Forms.Control[] {
																		  this.labelParentException,
																		  this.labelParentExceptionTitle,
																		  this.labelInnerException,
																		  this.labelInnerExceptionTitle,
																		  this.tabControlExceptionExplorerPages});
			this.Name = "ExceptionExplorerControl";
			this.Size = new System.Drawing.Size(404, 404);
			this.tabControlExceptionExplorerPages.ResumeLayout(false);
			this.tabPageStandardInfo.ResumeLayout(false);
			this.tabPageToString.ResumeLayout(false);
			this.ResumeLayout(false);

		}
		#endregion

		public void LoadException(TestException te, string AssociatedTestPath)
		{
			if (te == null)
			{
				throw new Exception("Exception is null and cannot be loaded into the Exception Explorer.");
			}

			this.associatedTestPath = AssociatedTestPath;

			if (ExceptionIsInHierarchy(te))
			{
				SetActiveExceptionInHierarchy(te);
			}
			else
			{
				BuildNewExceptionHierarchy(te);
			}

			SetParentException();
			SetInnerException();

			if (te.Message != null)
			{
				textBoxMessage.Text = te.Message.Replace("\n", "\r\n");
			}
			else 
			{
				textBoxMessage.Text = "null";
			}

			if (te.Source != null)
			{
				textBoxSource.Text = te.Source;
			}
			else
			{
				textBoxSource.Text = "null";
			}

			if (te.Type != null && te.Type.ExceptionType != null)
			{
				textBoxType.Text = te.Type.ExceptionType;
			}
			else
			{
				textBoxType.Text = "unavailable";
			}

			if (te.ToStringText != null)
			{
				textBoxToString.Text = te.ToStringText.Replace("\n", "\r\n");
			}
			else
			{
				textBoxToString.Text = "null";
			}

			textBoxThreadID.Text = "0x" + te.ThreadID.ToString("X6");
			textBoxThreadName.Text = te.ThreadName;

			try
			{
				string name = AssociatedTestPath.Substring(AssociatedTestPath.ToLower().IndexOf("http://exceptionexplorer/") + 1);
				name = name.Replace("/", ".") + "()";
				textBoxTestMethod.Text = name;
			} 
			catch
			{
				textBoxTestMethod.Text = "Unknown";
			}

			LoadStackTrace(te);

			//
			// Fire exception changed event so the rest of the GUI can update itself if necessary.
			//
			if (CurrentExceptionChangedHandler != null)
			{
				CurrentExceptionChangedHandler(te, associatedTestPath);
			}
		}

		private void SetParentException()
		{
			string fontFace = labelParentException.Font.FontFamily.Name;
			float fontSize = labelParentException.Font.Size;
			if (ParentException == null)
			{
				labelParentExceptionTitle.Text = "Parent Exception";
				labelParentException.Text = "None";

				labelParentException.Font = new Font(fontFace, fontSize, FontStyle.Regular);
				labelParentException.ForeColor = Color.Black;
				labelParentException.Cursor = Cursors.Default;
			}
			else
			{
				labelParentExceptionTitle.Text = "Parent Exception (Click to view Parent exception details)";
				labelParentException.Text = ParentException.Type.ExceptionType;
				
				labelParentException.Font = new Font(fontFace, fontSize, FontStyle.Underline);
				labelParentException.ForeColor = Color.Blue;
				labelParentException.Cursor = Cursors.Hand;
			}
		}

		private void SetInnerException()
		{
			string fontFace = labelInnerException.Font.FontFamily.Name;
			float fontSize = labelInnerException.Font.Size;
			if (InnerException == null)
			{
				labelInnerExceptionTitle.Text = "Inner Exception";
				labelInnerException.Text = "None";

				labelInnerException.Font = new Font(fontFace, fontSize, FontStyle.Regular);
				labelInnerException.ForeColor = Color.Black;
				labelInnerException.Cursor = Cursors.Default;
			}
			else
			{
				labelInnerExceptionTitle.Text = "Inner Exception (Click to view inner exception details)";
				labelInnerException.Text = InnerException.Type.ExceptionType;
				
				labelInnerException.Font = new Font(fontFace, fontSize, FontStyle.Underline);
				labelInnerException.ForeColor = Color.Blue;
				labelInnerException.Cursor = Cursors.Hand;
			}
		}

		private void labelInnerException_Click(object sender, System.EventArgs e)
		{
			if (InnerException != null)
			{
				LoadException(InnerException, associatedTestPath);
			}
		}

		public void Clear()
		{
			textBoxMessage.Text		= initialNoExceptionMessage;
			textBoxToString.Text	= initialNoExceptionMessage;
			textBoxSource.Text		= "";
			textBoxType.Text		= "";
			textBoxTestMethod.Text	= "";
			
			listViewStackTrace.Items.Clear();

			exceptionHierarchy.Clear();
			currentExceptionIndex = 0;

			SetInnerException();
			SetParentException();

			tabControlExceptionExplorerPages.SelectedTab = tabPageStandardInfo;
		}

		private void LoadStackTrace(TestException te)
		{
			listViewStackTrace.Items.Clear();

			if (te == null || te.StackTrace == null || te.StackTrace.Length == 0 || te.StackTrace == "null")
			{
				return;
			}

			try
			{
				StackTraceParser parser = new StackTraceParser(te.StackTrace);

				StackTraceEntry [] entries = parser.Entries;

				foreach (StackTraceEntry ste in entries)
				{
					//				
					// Create a new list view item based on this information and add it to the list view.
					//
					string lineText = ste.Line > 0 ? ste.Line.ToString() : "";
					string [] subitems = new String [] 
										{
											ste.Method,
											ste.ClassName,
											lineText,
											ste.File,
											ste.NameSpace
										};

					ListViewItem item = new ListViewItem(subitems);
					listViewStackTrace.Items.Add(item);
				}
			}
			catch (Exception ex)
			{ 
				listViewStackTrace.Items.Clear();
				listViewStackTrace.Items.Add("Unavailable. Details: " + ex.ToString());
			}
		}

		private void SelectEveryTabPage()
		{
			tabControlExceptionExplorerPages.SelectedTab = tabPageToString;
			tabControlExceptionExplorerPages.SelectedTab = tabPageStandardInfo;
		}

		private void labelParentException_Click(object sender, System.EventArgs e)
		{
			if (ParentException != null)
			{
				LoadException(ParentException, associatedTestPath);
			}		
		}

		private Exception CurrentException
		{
			get
			{
				int index = currentExceptionIndex;
				if (index >= exceptionHierarchy.Count || index < 0)
				{
					return null;
				}
				return (Exception)exceptionHierarchy[index];
			}
		}

		private TestException ParentException
		{
			get
			{
				int index = currentExceptionIndex - 1;
				if (index >= exceptionHierarchy.Count || index < 0)
				{
					return null;
				}
				return (TestException)exceptionHierarchy[index];
			}
		}

		private TestException InnerException
		{
			get
			{
				int index = currentExceptionIndex + 1;
				if (index >= exceptionHierarchy.Count || index < 0)
				{
					return null;
				}
				return (TestException)exceptionHierarchy[index];
			}
		}

		private bool ExceptionIsInHierarchy(TestException te)
		{
			return (exceptionHierarchy.IndexOf(te) >= 0);
		}

		private void SetActiveExceptionInHierarchy(TestException te)
		{
			if (!ExceptionIsInHierarchy(te))
			{
				throw new Exception("Exception could not be located in exception heirarchy.");
			}
			currentExceptionIndex = exceptionHierarchy.IndexOf(te);
		}
		
		private void BuildNewExceptionHierarchy(TestException te)
		{
			currentExceptionIndex = 0;
			exceptionHierarchy.Clear();
			exceptionHierarchy.Add(te);

			TestException tmpE = te.InnerException;
			while (tmpE != null)
			{
				exceptionHierarchy.Add(tmpE);
				tmpE = tmpE.InnerException;
			}
		}

		private void timerUpdatePersistence_Tick(object sender, System.EventArgs e)
		{
			stPersist.Save();
		}
	}
}
